# @Time : 2024-10-19 13:12
# @Author : Fioman 
# @Phone : 13149920693
"""
字典: Python的字典是一种用来存储键值对的数据结构,特点是快速查找,插入和删除操作.基于哈希表.
它的键必须是不可变对象,值可以任何类型的数据.
"""
# region 1. 字典的创建
# 1) 普通字典创建
emptyDt = dict()
emptyDt2 = {}
dt = {"name": "Fioman", "age": 18}
# 2) dict() 函数构建字典
# 通过关键字参数来构建
myDt = dict(name="Fioman", age=18, gender="男")
print(myDt)
# 通过dict() 键值对列表或者键值对元组来构建
myDt = dict([("name", "Fioman"), ("age", 18), ("gender", "男")])
print(myDt)
myDt = dict((("name", "Fioman"), ("age", 18), ("gender", "男")))
print(myDt)
# 3) 使用字典推导式构建字典
myDt = {chr(x): x ** 2 for x in range(65, 80)}
print(myDt)
# 4) 从两个列表元组中构建字典
nameList = ["Fioman", "John", "Bala"]
scoreList = [21, 34, 56]
myDt = dict(zip(nameList, scoreList))
print(myDt)
# 这样不行,因为这样是循环了9次,获取到了9个值
myDt = {(name, score) for name in nameList for score in scoreList}
print(myDt)
# 那么如果使用字典推导式,该如何实现呢?
myDt = {(nameList[i], scoreList[i]) for i in range(len(nameList))}
print(myDt)
# 5) 使用fromkeys() 方法构建字典,构建的字典具有相同的默认值
keys = {"name", "age", "gender"}
myDt = dict.fromkeys(keys, "未定义")
print(myDt)
# 6) 构建嵌套字典
nestedDt = {
    "student1": {"name": "Fioman", "age": 18},
    "student2": {"name": "Bala", "age": 18},
}
print(nestedDt)
# endregion
# region 2. 字典的长度 len(dict)
myDt = {chr(i): i for i in range(65, 70)}
print(myDt, len(myDt))
# endregion

# region 3. 访问字典的项
myDt = {chr(i): i for i in range(100, 110)}
print(myDt, len(myDt))
print(myDt[chr(100)])  # 通过键访问
# print(myDt[chr(1000)])  # 如果键不存在就报错
print(myDt.get(chr(1000)))  # 如果通过get的方式不存在的话不报错返回None,或者后面可以加个默认值
print(myDt.get(chr(1000), 0))
# endregion

# region 4. 往字典中添加项 dict[index] = dictVal
myDt = dict()
myDt["A"] = 123  # 如果键不存在是添加
myDt["B"] = 456
print(myDt)
myDt["A"] = 1000  # 如果键已经存在就是修改
print(myDt)
# endregion

# region 5. 删除键值对 del | pop()
myDt = {chr(i): i for i in range(65, 70)}
del myDt["B"]
print(myDt)
# del myDt["Z"]  # 如果要删除的不存在,报错
popVal = myDt.pop("A")  # 根据键删除键值对,并返回对应的值,pop()后面的参数一定要存在的
print(f"after pop :{myDt},popVal: {popVal}")
# popVal = myDt.pop("Z") # 如果要pop的不存在也会报错
# endregion

# region 6. 检查键或者值是否存在
myDt = {chr(i): i for i in range(65, 70)}
if "A" in myDt:
    print("A is in Dict")
else:
    print("A is not in Dict")
if 65 in myDt.values():
    print(f"65 in Dict.Values()")
else:
    print(f"65 not in Dict.Values()")
# endregion

# region 7. 清空字典 和 删除字典
myDt = {chr(i): i for i in range(65, 70)}
myDt.clear()
print(myDt)
del myDt
# print(myDt) # 报错,已删除没发再访问
# endregion
# region 8. 复制字典
myDt = {"name": "Fioman", "age": 18}
myDtCopy = myDt.copy()
print(myDtCopy)
# endregion

# region 8. 字典的键值对列表,键列表,值列表     items() | keys() | values()
myDt = {chr(i): i for i in range(65, 70)}
items = myDt.items()  # 可迭代对象
keys = myDt.keys()  # 可迭代对象
values = myDt.values()  # 可迭代对象
print(items, keys, values, type(items), type(keys), type(values))
items = list(items)
keys = list(keys)
values = list(values)
print(items, keys, values, type(items), type(keys), type(values))
# endregion

# region 9. 合并字典 更新键值对 update
myDt = {"name": "Fioman", "age": 18}
myDt2 = {"score": 100, "gender": "男"}
myDt.update(myDt2)  # 合并字典
print(myDt)
# 如果要合并的字典和原来的字典的键相同,就变成了更新字典
myDt.update({"name": "Lisa"})
print(myDt)
# endregion

# region 10. 遍历字典
myDt = {chr(i): i for i in range(65, 70)}
for key, value in myDt.items():
    print(f"key: {key},value:{value}")

for key in myDt:  # 默认是遍历key
    print(f"key: {key}")

for key in myDt.keys():
    print(f"key: {key}")

for value in myDt.values():
    print(f"value: {value}")
# endregion

# region 11. 带有默认值的dict defaultdict
# collections.defaultdict 允许你再访问不存在的键时自动为其赋默认值避免KeyError
# 并且这个键会自动的添加到字典中去
from collections import defaultdict

defaultDt = defaultdict(list)
print(defaultDt["a"])
print(defaultDt)
defaultDt["b"].append(10)  # 会自动添加到字典中去
print(defaultDt)

# endregion

# region 12.  保留了插入顺序的字典(py3.7 之后内置字典也支持这一特性)
from collections import OrderedDict

orderDt = OrderedDict()
orderDt["name"] = "Fioman"
orderDt["age"] = 18
orderDt["gender"] = "男"
orderDt["score"] = 100
print(orderDt)  # 保留了插入的顺序
myDt = dict()
myDt["name"] = "Fioman"
myDt["score"] = 100
myDt["gender"] = "女"
myDt["age"] = 20
print(myDt)  # 也保留了顺序
# endregion

# region 13. 为键设置默认值,如果已经存在就返回该键对应的值,不存在就设置一个默认值
myDt = dict()
age = myDt.setdefault("age", 18)
name = myDt.setdefault("name", "Fioman")
print(myDt, age, name)
age = myDt.setdefault("age", 22)  # 18 age已经存在了
print(age)
# endregion

# region 14. 练习
dogDt = dict()
dogDt["name"] = "大黄"
dogDt["color"] = "黄色"
dogDt["breed"] = "金毛"
dogDt["legs"] = 4
dogDt["age"] = 2
stuDict = {
    "name": "Fioman",
    "gender": "男",
    "age": 18,
    "maritalStatus": "未婚",
    "skills": ["Python", "C#"],
    "country": "中国",
    "city": "深圳",
    "address": "深圳宝安"
}
print(len(stuDict))
skills = stuDict.get("skills")
print(skills, type(skills))
stuDict["skills"] = ["Python", "C#", "JavaScript"]
print(stuDict["skills"])
keysList = list(stuDict.keys())
valuesList = list(stuDict.values())
print(keysList, valuesList)
popVal = stuDict.pop("city")
print(stuDict, f"popVal: {popVal}")
del stuDict
# endregion
